﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainWindowViewModel.cs" company="Concept Architecture">
//   (c) 2010 Muhammad Umer Farooq
// </copyright>
// <summary>
//   Defines the MainWindowViewModel type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Hisaab.Windows.Client.ViewModel
{
    using System;
    using System.Collections.ObjectModel;
    using System.Diagnostics.Contracts;
    using System.Linq;
    using System.Windows.Forms;
    using System.Windows.Input;
    using Business.Interfaces;
    using Common;
    using Documents;
    using Hisaab.Common;

    using Microsoft.Practices.ServiceLocation;

    using Model;
    using Properties;
    using Application = System.Windows.Application;
    using MessageBox = System.Windows.MessageBox;
    using Transaction = Model.Transaction;

    /// <summary>
    /// Defines the <seealso cref="MainWindowViewModel"/> type.
    /// </summary>
    public class MainWindowViewModel
    {
        /// <summary>
        /// Save command
        /// </summary>
        public static readonly ActiveAwareCommand SaveCommand = new ActiveAwareCommand();

        /// <summary>
        /// Account object
        /// </summary>
        private readonly IAccountManager _accountManager;

        /// <summary>
        /// The session
        /// </summary>
        private readonly ISession _session;

        /// <summary>
        /// Accounts list
        /// </summary>
        private ObservableCollection<Account> _accounts;

        #region Delegates

        #region New Commands

        /// <summary>
        /// New Account command
        /// </summary>
        private DelegateCommand _newAccountCommand;

        /// <summary>
        /// New Transaction Command
        /// </summary>
        private DelegateCommand _newTransactionCommand;

        /// <summary>
        /// New tag command
        /// </summary>
        private DelegateCommand _newTagCommand;

        /// <summary>
        /// New vehicle command
        /// </summary>
        private DelegateCommand _newVehicleCommand;

        /// <summary>
        /// New vehicle transaction command
        /// </summary>
        private DelegateCommand _newVehicleTransactionCommand;

        #endregion New Commands

        #region Open Commands

        /// <summary>
        /// Open Account Command
        /// </summary>
        private DelegateCommand _openAccountsCommand;

        /// <summary>
        /// Open Tags Command
        /// </summary>
        private DelegateCommand _openTagsCommand;

        /// <summary>
        /// Open transaction command
        /// </summary>
        private DelegateCommand _openTransactionsCommand;

        /// <summary>
        /// Open calculator command
        /// </summary>
        private DelegateCommand _openCalculatorCommand;

        /// <summary>
        /// Open Vehicle transfer command
        /// </summary>
        private DelegateCommand _openVehicleTransactionCommand;

        /// <summary>
        /// Open vehicle command
        /// </summary>
        private DelegateCommand _openVehicleCommand;

        /// <summary>
        /// Open dashboard command
        /// </summary>
        private DelegateCommand _openDashboardCommand;

        #endregion Open Commands

        #region Other Commands

        /// <summary>
        /// Backup command
        /// </summary>
        private DelegateCommand _backupCommand;

        /// <summary>
        /// Import command
        /// </summary>
        private DelegateCommand _restoreCommand;

        /// <summary>
        /// Options command
        /// </summary>
        private DelegateCommand _optionsCommand;

        /// <summary>
        /// Help Command
        /// </summary>
        private DelegateCommand _helpCommand;

        /// <summary>
        /// About command
        /// </summary>
        private DelegateCommand _aboutCommand;

        /// <summary>
        /// Exit command
        /// </summary>
        private DelegateCommand _exitCommand;

        #endregion Other Commands

        #endregion Delegates

        /// <summary>
        /// Initializes a new instance of the <see cref="MainWindowViewModel"/> class.
        /// </summary>
        public MainWindowViewModel()
            : this(
            ServiceLocator.Current.GetInstance<IAccountManager>(),
            ServiceLocator.Current.GetInstance<ISession>())
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="MainWindowViewModel"/> class.
        /// </summary>
        /// <param name="accountManager">Transaction manager</param>
        /// <param name="session">The session</param>
        public MainWindowViewModel(IAccountManager accountManager, ISession session)
        {
            Contract.Requires<ArgumentNullException>(accountManager != null);
            Contract.Requires<ArgumentNullException>(session != null);

            _accountManager = accountManager;
            _session = session;
            DocumentContents = new ObservableCollection<AvalonDock.DocumentContent>();

            Title = string.Format("{0} - {1}", Resources.ApplicationName, Resources.ApplicationSlogan);
        }

        #region Properties

        /// <summary>
        /// Gets the document contents.
        /// </summary>
        public ObservableCollection<AvalonDock.DocumentContent> DocumentContents { get; private set; }

        /// <summary>
        /// Gets or sets the title.
        /// </summary>
        /// <value>
        /// The title.
        /// </value>
        public string Title { get; set; }

        /// <summary>
        /// Gets the Account Types.
        /// </summary>
        public ObservableCollection<Account> Accounts
        {
            get
            {
                if (_accounts == null)
                {
                    _accounts = new ObservableCollection<Account>(
                        _accountManager
                            .List(new Business.Entities.Account { UserId = _session.LoggedUser })
                            .Select(x => x.Map<Business.Entities.Account, Account>()));
                }

                return _accounts;
            }
        }

        /// <summary>
        /// Gets or sets the filter transaction.
        /// </summary>
        /// <value>The filter transaction.</value>
        public Transaction FilterTransaction { get; set; }

        #endregion Properties

        #region Commands

        #region New Commands

        /// <summary>
        /// Gets the open accounts.
        /// </summary>
        public ICommand NewAccountCommand
        {
            get
            {
                if (_newAccountCommand == null)
                {
                    _newAccountCommand = new DelegateCommand(OnNewAccount);
                }

                return _newAccountCommand;
            }
        }

        /// <summary>
        /// Gets the new transaction command.
        /// </summary>
        public ICommand NewTransactionCommand
        {
            get
            {
                if (_newTransactionCommand == null)
                {
                    _newTransactionCommand = new DelegateCommand(OnNewTransaction);
                }

                return _newTransactionCommand;
            }
        }

        /// <summary>
        /// Gets the new tag command.
        /// </summary>
        public ICommand NewTagCommand
        {
            get
            {
                if (_newTagCommand == null)
                {
                    _newTagCommand = new DelegateCommand(OnNewTag);
                }

                return _newTagCommand;
            }
        }

        /// <summary>
        /// Gets the new vehicle command.
        /// </summary>
        public ICommand NewVehicleCommand
        {
            get
            {
                if (_newVehicleCommand == null)
                {
                    _newVehicleCommand = new DelegateCommand(OnNewVehicle);
                }

                return _newVehicleCommand;
            }
        }

        /// <summary>
        /// Gets the new vehicle transaction command.
        /// </summary>
        public ICommand NewVehicleTransactionCommand
        {
            get
            {
                if (_newVehicleTransactionCommand == null)
                {
                    _newVehicleTransactionCommand = new DelegateCommand(OnNewVehicleTransaction);
                }

                return _newVehicleTransactionCommand;
            }
        }

        #endregion New Commands

        #region Open Commands

        /// <summary>
        /// Gets the open accounts.
        /// </summary>
        public ICommand OpenAccountsCommand
        {
            get
            {
                if (_openAccountsCommand == null)
                {
                    _openAccountsCommand = new DelegateCommand(OnOpenAccounts);
                }

                return _openAccountsCommand;
            }
        }

        /// <summary>
        /// Gets the open tags.
        /// </summary>
        public ICommand OpenTagsCommand
        {
            get
            {
                if (_openTagsCommand == null)
                {
                    _openTagsCommand = new DelegateCommand(OnOpenTags);
                }

                return _openTagsCommand;
            }
        }

        /// <summary>
        /// Gets the open transactions command.
        /// </summary>
        public ICommand OpenTransactionsCommand
        {
            get
            {
                if (_openTransactionsCommand == null)
                {
                    _openTransactionsCommand = new DelegateCommand(OnOpenTransactions);
                }

                return _openTransactionsCommand;
            }
        }

        /// <summary>
        /// Gets the open calculator command.
        /// </summary>
        public ICommand OpenCalculatorCommand
        {
            get
            {
                if (_openCalculatorCommand == null)
                {
                    _openCalculatorCommand = new DelegateCommand(OnOpenCalculator);
                }

                return _openCalculatorCommand;
            }
        }

        /// <summary>
        /// Gets the open Vehicle transactions command.
        /// </summary>
        public ICommand OpenVehicleTransactionsCommand
        {
            get
            {
                if (_openVehicleTransactionCommand == null)
                {
                    _openVehicleTransactionCommand = new DelegateCommand(OnOpenVehicleTransactions);
                }

                return _openVehicleTransactionCommand;
            }
        }

        /// <summary>
        /// Gets the open Vehicle transactions command.
        /// </summary>
        public ICommand OpenVehiclesCommand
        {
            get
            {
                if (_openVehicleCommand == null)
                {
                    _openVehicleCommand = new DelegateCommand(OnOpenVehicles);
                }

                return _openVehicleCommand;
            }
        }

        /// <summary>
        /// Gets the open dashboard command.
        /// </summary>
        public ICommand OpenDashboardCommand
        {
            get
            {
                if (_openDashboardCommand == null)
                {
                    _openDashboardCommand = new DelegateCommand(OnDashboard);
                }

                return _openDashboardCommand;
            }
        }

        #endregion Open Commands

        #region Other Commands

        /// <summary>
        /// Gets the help command.
        /// </summary>
        public ICommand HelpCommand
        {
            get
            {
                if (_helpCommand == null)
                {
                    _helpCommand = new DelegateCommand(OnHelp);
                }

                return _helpCommand;
            }
        }

        /// <summary>
        /// Gets the Backup command.
        /// </summary>
        public ICommand BackupCommand
        {
            get
            {
                if (_backupCommand == null)
                {
                    _backupCommand = new DelegateCommand(OnBackup);
                }

                return _backupCommand;
            }
        }

        /// <summary>
        /// Gets the import command.
        /// </summary>
        public ICommand ResotreCommand
        {
            get
            {
                if (_restoreCommand == null)
                {
                    _restoreCommand = new DelegateCommand(OnResotre);
                }

                return _restoreCommand;
            }
        }

        /// <summary>
        /// Gets the options command.
        /// </summary>
        public ICommand OptionsCommand
        {
            get
            {
                if (_optionsCommand == null)
                {
                    _optionsCommand = new DelegateCommand(OnOptions);
                }

                return _optionsCommand;
            }
        }

        /// <summary>
        /// Gets the options command.
        /// </summary>
        public ICommand AboutCommand
        {
            get
            {
                if (_aboutCommand == null)
                {
                    _aboutCommand = new DelegateCommand(OnAbout);
                }

                return _aboutCommand;
            }
        }

        /// <summary>
        /// Gets the exit command.
        /// </summary>
        public ICommand ExitCommand
        {
            get
            {
                if (_exitCommand == null)
                {
                    _exitCommand = new DelegateCommand(OnExit);
                }

                return _exitCommand;
            }
        }

        #endregion Other Commands

        #endregion Commands

        #region Command Handlers

        #region New Command Event Handlers

        /// <summary>
        /// Called when new account
        /// </summary>
        private void OnDashboard()
        {
            var viewModel = new DashboardViewModel();
            var accountsDocument = new DashboardDocument(viewModel);

            DocumentManager.Instance.ActiveDocument = accountsDocument;
        }

        /// <summary>
        /// Called when new account
        /// </summary>
        private void OnNewAccount()
        {
            var viewModel = new AccountEditorViewModel(null);
            var accountsDocument = new AccountEditorDocument(viewModel);

            DocumentManager.Instance.ActiveDocument = accountsDocument;
        }

        /// <summary>
        /// Called when new transaction.
        /// </summary>
        private void OnNewTransaction()
        {
            var viewModel = new TransactionEditorViewModel(null);
            var transactionsDocument = new TransactionEditorDocument(viewModel);

            DocumentManager.Instance.ActiveDocument = transactionsDocument;
        }

        /// <summary>
        /// Called when new tag.
        /// </summary>
        private void OnNewTag()
        {
            var editorViewModel = new TagEditorViewModel(null);
            ServiceLocator.Current.GetInstance<IWindowDialogService>().ShowDialog("New Tag", editorViewModel);
        }

        /// <summary>
        /// Called when new vehicle.
        /// </summary>
        private void OnNewVehicle()
        {
            //var dataImport = new DataImport();
            //dataImport.ImportCsvData(@"D:\Desktop\Accounts\export");
            //var editorViewModel = new VehicleEditorViewModel(null);
            //ServiceLocator.Current.GetInstance<IWindowDialogService>().ShowDialog("New Vehicle", editorViewModel);
        }

        /// <summary>
        /// Called when new transaction.
        /// </summary>
        private void OnNewVehicleTransaction()
        {
            var viewModel = new VehicleTransactionEditorViewModel(null);
            var vehicleTransactionsDocument = new VehicleTransactionEditorDocument(viewModel);

            DocumentManager.Instance.ActiveDocument = vehicleTransactionsDocument;
        }

        #endregion New Command Event Handlers

        #region Open Command Event Handlers

        /// <summary>
        /// Called when [open accounts].
        /// </summary>
        private void OnOpenAccounts()
        {
            var viewModel = new AccountsViewModel();
            var accountsDocument = new AccountsDocument(viewModel);

            DocumentManager.Instance.ActiveDocument = accountsDocument;
        }

        /// <summary>
        /// Called when open tags.
        /// </summary>
        private void OnOpenTags()
        {
            var viewModel = new TagsViewModel();
            var tagsDocument = new TagsDocument(viewModel);

            DocumentManager.Instance.ActiveDocument = tagsDocument;
        }

        /// <summary>
        /// Called when open transactions.
        /// </summary>
        private void OnOpenTransactions()
        {
            var viewModel = new TransactionsViewModel();
            var transactionsDocument = new TransactionsDocument(viewModel);
            DocumentManager.Instance.ActiveDocument = transactionsDocument;
        }

        /// <summary>
        /// Called when open transactions.
        /// </summary>
        private void OnOpenVehicleTransactions()
        {
            var viewModel = new VehicleTransactionsViewModel();
            var transactionsDocument = new VehicleTransactionsDocument(viewModel);
            DocumentManager.Instance.ActiveDocument = transactionsDocument;
        }

        /// <summary>
        /// Called when open vehicle.
        /// </summary>
        private void OnOpenVehicles()
        {
            var viewModel = new VehiclesViewModel();
            var vehiclesDocument = new VehiclesDocument(viewModel);
            DocumentManager.Instance.ActiveDocument = vehiclesDocument;
        }

        #endregion Open Command Event Handlers

        #region Other Command Event Handlers

        /// <summary>
        /// Called when help.
        /// </summary>
        private void OnHelp()
        {
        }

        /// <summary>
        /// Called when [backup].
        /// </summary>
        private void OnBackup()
        {
            ServiceLocator.Current.GetInstance<IWindowDialogService>()
                .ShowDialog("Backup", new BackupViewModel());
        }

        /// <summary>
        /// Called when [import].
        /// </summary>
        private void OnResotre()
        {
            // throw new NotImplementedException();
        }

        /// <summary>
        /// Called when options.
        /// </summary>
        private void OnOptions()
        {
            // throw new NotImplementedException();
        }

        /// <summary>
        /// Called when options.
        /// </summary>
        private void OnAbout()
        {
            ServiceLocator.Current.GetInstance<IWindowDialogService>().ShowMessage("Created by Umer Farooq");
        }

        /// <summary>
        /// Called when [open calculator].
        /// </summary>
        private void OnOpenCalculator()
        {
            //var dataImport = new DataImport();
            //dataImport.ImportCsvData(@"D:\Desktop\Account");

            try
            {
                System.Diagnostics.Process.Start("calc.exe");
            }
            catch (Exception ex)
            {
                MessageBox.Show(Resources.ApplicationName, "Error launching calculator." + Environment.NewLine + ex.Message);
            }
        }

        /// <summary>
        /// Called when exit.
        /// </summary>
        private void OnExit()
        {
            if (ServiceLocator.Current.GetInstance<IWindowDialogService>().ShowMessage(
                  "Are you sure you want to exit Hisaab?",
                  "Hissab",
                  MessageBoxButtons.YesNo,
                  MessageBoxIcon.Question)
                  == DialogResult.Yes)
            {
                Application.Current.MainWindow.Close();
            }
        }

        #endregion Other Command Event Handlers

        #endregion Command Handlers
    }
}